#include "EventEngine.h"
#include "LogManager.h"
#include <QTimer>
#include <QEventLoop>

EventEngine* EventEngine::instance() {
    static EventEngine instance;
    return &instance;
}

EventEngine::EventEngine(QObject* parent) : QObject(parent) {
    this->moveToThread(&m_eventThread);
    connect(&m_eventThread, &QThread::started, this, &EventEngine::started);
    connect(&m_eventThread, &QThread::finished, this, &EventEngine::stopped);
}

EventEngine::~EventEngine() {
    stop();
}

void EventEngine::start() {
    if (m_running) return;
    
    m_running = true;
    m_eventThread.start();
    QMetaObject::invokeMethod(this, "processEvents", Qt::QueuedConnection);
    m_timerThread.start();
    QMetaObject::invokeMethod(this, "timerThread", Qt::QueuedConnection);
    
    MLOG_INFO("event", "Event engine started");
}

void EventEngine::stop() {
    if (!m_running) return;
    
    m_running = false;
    m_condition.notify_all();
    
    if (m_eventThread.isRunning()) {
        m_eventThread.quit();
        m_eventThread.wait();
    }
    
    if (m_timerThread.isRunning()) {
        m_timerThread.quit();
        m_timerThread.wait();
    }
    
    MLOG_INFO("event", "Event engine stopped");
}

void EventEngine::registerHandler(EventType type, const EventHandler& handler) {
    std::lock_guard<std::mutex> lock(m_handlerMutex);
    m_handlers[type].push_back(handler);
}

void EventEngine::unregisterHandler(EventType type) {
    std::lock_guard<std::mutex> lock(m_handlerMutex);
    m_handlers.erase(type);
}

void EventEngine::postEvent(Event&& event) {
    {
        std::lock_guard<std::mutex> lock(m_queueMutex);
        m_eventQueue.push(std::move(event));
    }
    m_condition.notify_one();
}

size_t EventEngine::queueSize() const {
    std::lock_guard<std::mutex> lock(m_queueMutex);
    return m_eventQueue.size();
}

void EventEngine::processEvents() {
    while (m_running) {
        Event event;
        {
            std::unique_lock<std::mutex> lock(m_queueMutex);
            m_condition.wait(lock, [this] { 
                return !m_eventQueue.empty() || !m_running; 
            });
            
            if (!m_running) break;
            
            event = std::move(m_eventQueue.front());
            m_eventQueue.pop();
        }
        
        std::lock_guard<std::mutex> lock(m_handlerMutex);
        auto it = m_handlers.find(event.type());
        if (it != m_handlers.end()) {
            for (const auto& handler : it->second) {
                try {
                    handler(event);
                } catch (const std::exception& e) {
                    MLOG_ERROR("event", "Error handling event type {}: {}", 
                        static_cast<int>(event.type()), e.what());
                }
            }
        }
    }
}

void EventEngine::timerThread() {
    QTimer timer;
    timer.setInterval(1000);  // 1秒定时
    
    connect(&timer, &QTimer::timeout, this, [this]() {
        postEvent(Event(EventType::Timer));
    });
    
    timer.start();
    
    QEventLoop loop;
    while (m_running) {
        loop.processEvents();
    }
    
    timer.stop();
} 